package matheus.tp01cg;

import matheus.tp01cg.objetosdedesenho.Circunferencia;
import matheus.tp01cg.objetosdedesenho.Coords;
import matheus.tp01cg.objetosdedesenho.DesenhoComposto;
import matheus.tp01cg.objetosdedesenho.FabricaDeObjetoDeDesenho;
import matheus.tp01cg.objetosdedesenho.FabricaDeObjetoDeDesenho.AlgoritmosReta;
import matheus.tp01cg.objetosdedesenho.ObjetoDeDesenho;
import matheus.tp01cg.objetosdedesenho.Poligono;
import matheus.tp01cg.objetosdedesenho.Reta;
import matheus.tp01cg.objetosdedesenho.Retangulo;
import matheus.tp01cg.objetosdedesenho.recorte.FabricaDeRecorte;
import matheus.tp01cg.objetosdedesenho.recorte.FabricaDeRecorte.AlgoritmoRecorteReta;
import matheus.tp01cg.objetosdedesenho.recorte.Recorte;
import matheus.tp01cg.preenchimento.Preechimento;
import matheus.tp01cg.preenchimento.Preechimento.OnPreechimentoPronto;
import yuku.ambilwarna.AmbilWarnaDialog;
import yuku.ambilwarna.AmbilWarnaDialog.OnAmbilWarnaListener;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;

public class TP01CG extends Activity implements OnTouchListener,
		OnClickListener, OnPreechimentoPronto, OnAmbilWarnaListener {

	public static final int RAIO_SELECAO_ELEMENTOS_TRANSFORMACAO = 20;
	public static final int RAIO_SELECAO = 35;
	
	private AreaDeDesenho areaDeDesenho;

	private DesenhoComposto desenhos = new DesenhoComposto();

	/**
	 * Cria o bitmap baseado no tamanho da tela
	 */
	public Bitmap criarBitmap() {
		Bitmap bitmap = Bitmap.createBitmap(getWindowManager()
				.getDefaultDisplay().getWidth(), getWindowManager()
				.getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
		return bitmap;
	}

	private Button botaoFecharPoligono;
	private Button botaoInterromperPreechimento;
	private Button botaoExecutarRecorte;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (savedInstanceState == null) {
			setContentView(R.layout.main);

			areaDeDesenho = (AreaDeDesenho) findViewById(R.id.areaDeDesenho);
			areaDeDesenho.setOnTouchListener(this);
			botaoFecharPoligono = (Button) findViewById(R.id.botaoFecharPoligono);
			botaoExecutarRecorte = (Button) findViewById(R.id.botaoExecutarRecorte);
			botaoExecutarRecorte.setOnClickListener(this);
			botaoFecharPoligono.setOnClickListener(this);
			botaoInterromperPreechimento = (Button) findViewById(R.id.botaoInterromperPreenchimento);
			botaoInterromperPreechimento.setOnClickListener(this);
			areaDeDesenho.bitmap = criarBitmap();
			Preechimento.setOnPreechimentoPronto(this);
		}
	}

	@Override
	public void onAttachedToWindow() {
		super.onAttachedToWindow();
		openOptionsMenu();
	}

	/**
	 * Redesenha no canvas
	 */
	private void redesenhar() {
		Log.v(null, "redesenhou");
		areaDeDesenho.bitmap.eraseColor(Color.TRANSPARENT);
		desenhos.desenha(areaDeDesenho.bitmap);
		if (retanguloSelecao != null)
			retanguloSelecao.desenha(areaDeDesenho.bitmap);
	}

	/**
	 * Limpa todos os desenhos
	 */
	private void limpar() {
		areaDeDesenho.bitmap.eraseColor(Color.TRANSPARENT);
		desenhos.listaDeDesenhos.clear();
		openOptionsMenu();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu_principal, menu);
		return true;
	}

	public static enum Acao {
		NENHUMA, MOVER, DESENHAR_RETA, DESENHAR_POLIGONO, DESENHAR_RETANGULO, DESENHAR_CIRCUNFERENCIA, PREECHIMENTO, RECORTE
	}

	public Acao acao = Acao.NENHUMA;

	public static enum AlgoritmoDePreenchimento {
		FLOOD_FILL, BOUNDARY_FILL
	}

	private AlgoritmoDePreenchimento algoritmoDePreenchimentoSelecionado = AlgoritmoDePreenchimento.FLOOD_FILL;

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menuItemMover:
			acao = Acao.MOVER;
			break;
		case R.id.menuItemReta:
			acao = Acao.DESENHAR_RETA;
			break;
		case R.id.menuItemPoligono:
			acao = Acao.DESENHAR_POLIGONO;
			break;
		case R.id.menuItemRetangulo:
			acao = Acao.DESENHAR_RETANGULO;
			break;
		case R.id.menuItemCircunferencia:
			acao = Acao.DESENHAR_CIRCUNFERENCIA;
			break;
		case R.id.menuItemFloodFill:
			algoritmoDePreenchimentoSelecionado = AlgoritmoDePreenchimento.FLOOD_FILL;
			acao = Acao.PREECHIMENTO;
			break;
		case R.id.menuItemBoundaryFill:
			algoritmoDePreenchimentoSelecionado = AlgoritmoDePreenchimento.BOUNDARY_FILL;
			acao = Acao.PREECHIMENTO;
			break;
		case R.id.menuItemRecortar:
			acao = Acao.RECORTE;
			break;
		case R.id.menuItemRedesenhar:
			acao = Acao.NENHUMA;
			redesenhar();
			break;
		case R.id.menuItemLimpar:
			acao = Acao.NENHUMA;
			limpar();
			break;
		case R.id.menuItemDDA:
			acao = Acao.NENHUMA;
			item.setChecked(true);
			fabricaDeObjetoDeDesenho.algoritmoReta = AlgoritmosReta.DDA;
			if (!desenhos.listaDeDesenhos.isEmpty())
				showDialog(DIALOG_CONFIRM_REDESENHA);
			cancelaRecorte();
			return true;
		case R.id.menuItemBresenham:
			acao = Acao.NENHUMA;
			item.setChecked(true);
			fabricaDeObjetoDeDesenho.algoritmoReta = AlgoritmosReta.BRESENHAM;
			if (!desenhos.listaDeDesenhos.isEmpty())
				showDialog(DIALOG_CONFIRM_REDESENHA);
			cancelaRecorte();
			return true;
		case R.id.menuItemLiangBarsky:
			acao = Acao.NENHUMA;
			item.setChecked(true);
			fabricaDeRecorte.algoritmoRecorteReta = AlgoritmoRecorteReta.LIANG_BARSKY;
			cancelaRecorte();
			return true;
		case R.id.menuItemCohenSutherLand:
			acao = Acao.NENHUMA;
			item.setChecked(true);
			fabricaDeRecorte.algoritmoRecorteReta = AlgoritmoRecorteReta.COHEN_SUTHERLAND;
			cancelaRecorte();
			return true;
		case R.id.menuItemCorPreenchimento:
			colorDialogPreechimento = new AmbilWarnaDialog(this,
					corPreenchimentoSelecionada, this);
			colorDialogPreechimento.show();
			break;
		case R.id.menuItemCorBorda:
			colorDialogBorda = new AmbilWarnaDialog(this, corBordaSelecionada,
					this);
			colorDialogBorda.show();
			break;
		case R.id.menuItemSobre:
			showDialog(DIALOG_SOBRE);
			return true;
		default:
			acao = Acao.NENHUMA;
			break;
		}
		cancelaRecorte();
		finalizaPoligonoSeNaoTiverSidoFeitoExplicitamente();
		return super.onOptionsItemSelected(item);
	}

	private static final int DIALOG_CONFIRM_REDESENHA = 1;

	private static final int DIALOG_SOBRE = 2;

	private AmbilWarnaDialog colorDialogPreechimento = null;

	private AmbilWarnaDialog colorDialogBorda = null;

	@Override
	protected Dialog onCreateDialog(int id) {
		Dialog dialog = null;
		AlertDialog.Builder builder;
		switch (id) {
		case DIALOG_CONFIRM_REDESENHA:
			builder = new AlertDialog.Builder(this);
			builder.setMessage("Deseja redesenhar a tela?")
					.setCancelable(false)
					.setPositiveButton("Sim",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									redesenhar();
								}
							})
					.setNegativeButton("Nao",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {
									dialog.cancel();
								}
							});
			dialog = builder.create();
			break;
		case DIALOG_SOBRE:
			builder = new AlertDialog.Builder(this);
			builder.setTitle(R.string.app_name)
					.setMessage(
							"PUC Minas - Bacharelado em Engenharia de Computação "
									+ "\nCurso de Computação Gráfica / 1o. sem. 2011"
									+ "\n\nAluno: Matheus Neder <matheusneder@gmail.com>"
									+ "\nProf.: Rosilane Ribeiro da Mota")
					.setCancelable(false)
					.setPositiveButton("Ok",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int id) {

								}
							});
			dialog = builder.create();
			break;
		}
		return dialog;
	}

	private ObjetoDeDesenho desenhoSelecionado = null;
	private ObjetoDeDesenho retanguloSelecao = null;

	private static final int PONTO_ROTACAO_NENHUM = -1;
	private static final int PONTO_ROTACAO_TOPO_ESQUERDA = 0;
	private static final int PONTO_ROTACAO_TOPO_DIREITA = 1;
	private static final int PONTO_ROTACAO_BASE_DIREITA = 2;
	private static final int PONTO_ROTACAO_BASE_ESQUERDA = 3;

	private static final int PONTO_ESCALA_NENHUM = -1;
	private static final int PONTO_ESCALA_TOPO_ESQUERDA = 0;
	private static final int PONTO_ESCALA_TOPO_MEIO = 1;
	private static final int PONTO_ESCALA_TOPO_DIREITA = 2;
	private static final int PONTO_ESCALA_DIREITA_MEIO = 3;
	private static final int PONTO_ESCALA_BASE_DIREITA = 4;
	private static final int PONTO_ESCALA_BASE_MEIO = 5;
	private static final int PONTO_ESCALA_BASE_ESQUERDA = 6;
	private static final int PONTO_ESCALA_ESQUERDA_MEIO = 7;

	

	private int obterPontoDeEscala(Coords ponto) {
		for (int i = 0; i < quadradinhosEscala.listaDeDesenhos.size(); i++) {
			if (quadradinhosEscala.listaDeDesenhos.get(i).intercepta(ponto,
					RAIO_SELECAO_ELEMENTOS_TRANSFORMACAO)) {
				return i;
			}
		}
		return PONTO_ESCALA_NENHUM;
	}

	private int obterPontoDeRotacao(Coords ponto) {
		for (int i = 0; i < setinhasRotacao.listaDeDesenhos.size(); i++) {
			if (setinhasRotacao.listaDeDesenhos.get(i).intercepta(ponto,
					RAIO_SELECAO_ELEMENTOS_TRANSFORMACAO)) {
				return i;
			}
		}
		return PONTO_ROTACAO_NENHUM;
	}

	private boolean transformando = false;

	private static enum TipoTransformacao {
		TRANSLADA, ESCALA, ROTACAO
	}

	private TipoTransformacao transformacaoAtiva;

	private Coords pontoTransfEventoAnt = new Coords(0, 0);
	private int pontoDeEscala = PONTO_ESCALA_NENHUM;
	private int pontoDeRotacao = PONTO_ROTACAO_NENHUM;
	private boolean transformou = false;

	private TipoTransformacao transformacaoCandidata = TipoTransformacao.ESCALA;

	private ObjetoDeDesenho desenhoPreviamenteSelecionado = null;

	private Coords centroRotacao = new Coords(0, 0);

	private void transformacaoInterativa(MotionEvent event) {
		int x = (int) Math.round(event.getX());
		int y = (int) Math.round(event.getY());
		Coords pontoTransfEventoAtual = new Coords(x, y);
		// inicializa
		if (!transformando) {
			boolean haviaDesenhoSelecionado = desenhoSelecionado != null;
			ObjetoDeDesenho desenhoQueIntercepta = null;
			if (desenhandoRetanguloParaRecorte) {
				desenhoQueIntercepta = desenhos.listaDeDesenhos
						.get(desenhos.listaDeDesenhos.size() - 1);
			}
			desenhoPreviamenteSelecionado = desenhoSelecionado; // suposicao

			if (haviaDesenhoSelecionado
					&& transformacaoCandidata == TipoTransformacao.ESCALA
					&& (pontoDeEscala = obterPontoDeEscala(pontoTransfEventoAtual)) != PONTO_ESCALA_NENHUM) {
				if (desenhandoRetanguloParaRecorte) {
					botaoExecutarRecorte.setVisibility(View.INVISIBLE);
				}
				transformacaoAtiva = TipoTransformacao.ESCALA;
				transformando = true;
				Log.v(null, "pontoDeEscala: " + pontoDeEscala);
			} else if (haviaDesenhoSelecionado
					&& transformacaoCandidata == TipoTransformacao.ROTACAO
					&& (pontoDeRotacao = obterPontoDeRotacao(pontoTransfEventoAtual)) != PONTO_ROTACAO_NENHUM) {
				transformacaoAtiva = TipoTransformacao.ROTACAO;
				centroRotacao.x = desenhoSelecionado.getCentro().x;
				centroRotacao.y = desenhoSelecionado.getCentro().y;
				transformando = true;
				Log.v(null, "pontoDeRotacao: " + pontoDeRotacao);
			} else if (desenhandoRetanguloParaRecorte
					|| (desenhoQueIntercepta = desenhos.interceptaQuem(
							pontoTransfEventoAtual, RAIO_SELECAO)) != null) {
				if (!haviaDesenhoSelecionado) {
					transformacaoCandidata = TipoTransformacao.ESCALA;
					desenhoPreviamenteSelecionado = null;
				}
				desenhoSelecionado = desenhoQueIntercepta;
				if (transformacaoCandidata == TipoTransformacao.ESCALA) {
					retanguloSelecao = destacarDesenhoModoEscala(desenhoSelecionado);
				} else if (transformacaoCandidata == TipoTransformacao.ROTACAO) {
					retanguloSelecao = destacarDesenhoModoRotacao(desenhoSelecionado);
				}
				transformacaoAtiva = TipoTransformacao.TRANSLADA;
				transformando = true;
				if (desenhandoRetanguloParaRecorte) {
					botaoExecutarRecorte.setVisibility(View.INVISIBLE);
				}
			}

			else {
				Log.v(null, "Nao intercepta");
				transformacaoCandidata = TipoTransformacao.ESCALA;
				desenhoSelecionado = null;
				if (retanguloSelecao != null) {
					retanguloSelecao = null;
					synchronized (areaDeDesenho.bitmap) {
						redesenhar();
					}
				}
			}

		} else if (event.getAction() == MotionEvent.ACTION_UP) { // finaliza
			if (desenhandoRetanguloParaRecorte) {
				botaoExecutarRecorte.setVisibility(View.VISIBLE);
			}
			if (transformou) {
				Log.v(null, "tranformou!");
				if (transformacaoAtiva == TipoTransformacao.ROTACAO) {
					retanguloSelecao = destacarDesenhoModoRotacao(desenhoSelecionado);
				}
			} else {
				Log.v(null, "NAO houve transformacao!");
				if (desenhoPreviamenteSelecionado == desenhoSelecionado) {
					if (transformacaoCandidata == TipoTransformacao.ESCALA
							&& !desenhandoRetanguloParaRecorte) {
						transformacaoCandidata = TipoTransformacao.ROTACAO;
						alternaParaModoDeRotacao();
					} else if (transformacaoCandidata == TipoTransformacao.ROTACAO) {
						alternaParaModoDeEscala();
						transformacaoCandidata = TipoTransformacao.ESCALA;
					}
				}
			}
			transformou = false;
			transformando = false;
			synchronized (areaDeDesenho.bitmap) {
				redesenhar();
			}
		} else { // transformando
			if (transformacaoAtiva == TipoTransformacao.TRANSLADA) {
				int deltaX = x - pontoTransfEventoAnt.x;
				int deltaY = y - pontoTransfEventoAnt.y;
				if (deltaX != 0 || deltaY != 0) {
					transformou = true;
					desenhoSelecionado.translada(deltaX, deltaY);
					retanguloSelecao.translada(deltaX, deltaY);
					synchronized (areaDeDesenho.bitmap) {
						redesenhar();
					}
				}
			} else if (transformacaoAtiva == TipoTransformacao.ROTACAO) {
				int deltaX = x - pontoTransfEventoAnt.x;
				int deltaY = y - pontoTransfEventoAnt.y;
				double sentido = 1;// 1 - horario, -1 - antihorarios
				// if (deltaX >= deltaY) {
				// if (x >= centroRotacao.x && y < centroRotacao.y) {
				// // 1o. quadrante
				// if (x < pontoTransfEventoAnt.x) {
				// sentido = -1;
				// }
				// } else if (x >= centroRotacao.x && y >= centroRotacao.y) {
				// // 4o. quadrante
				// if (x >= pontoTransfEventoAnt.x) {
				// sentido = -1;
				// }
				// } else if (x < centroRotacao.x && y >= centroRotacao.y) {
				// // 3o. quadrante
				// if (x >= pontoTransfEventoAnt.x) {
				// sentido = -1;
				// }
				// } else {
				// // 2o. quadrante
				// if (x < pontoTransfEventoAnt.x) {
				// sentido = -1;
				// }
				// }
				// } else {
				// if (x >= centroRotacao.x && y < centroRotacao.y) {
				// // 1o. quadrante
				// if (y < pontoTransfEventoAnt.y) {
				// sentido = -1;
				// }
				// } else if (x >= centroRotacao.x && y >= centroRotacao.y) {
				// // 4o. quadrante
				// if (y < pontoTransfEventoAnt.y) {
				// sentido = -1;
				// }
				// } else if (x < centroRotacao.x && y >= centroRotacao.y) {
				// // 3o. quadrante
				// if (y >= pontoTransfEventoAnt.y) {
				// sentido = -1;
				// }
				// } else {
				// // 2o. quadrante
				// if (y >= pontoTransfEventoAnt.y) {
				// sentido = -1;
				// }
				// }
				// }
				double variacao = Math.sqrt(Math.pow(deltaX, 2)
						+ Math.pow(deltaY, 2));
				double raio = Math.sqrt(Math.pow((x - centroRotacao.x), 2)
						+ Math.pow((y - centroRotacao.y), 2));
				double angulo = (variacao / raio) * sentido;
				Log.v(null, "angulo: " + angulo);
				desenhoSelecionado.rotaciona(centroRotacao, angulo);
				retanguloSelecao = null;// destacarDesenhoModoRotacao(desenhoSelecionado);
				transformou = true;

				synchronized (areaDeDesenho.bitmap) {
					redesenhar();
				}
			} else if (transformacaoAtiva == TipoTransformacao.ESCALA) {
				int novoDeltaX = 0, antDeltaX = 0, novoDeltaY = 0, antDeltaY = 0;
				Coords ref = null;
				try {
					switch (pontoDeEscala) {
					case PONTO_ESCALA_TOPO_ESQUERDA:
						ref = (Coords) desenhoSelecionado.getMax().clone();
						antDeltaX = desenhoSelecionado.getMinX()
								- desenhoSelecionado.getMaxX();
						antDeltaY = desenhoSelecionado.getMinY()
								- desenhoSelecionado.getMaxY();
						novoDeltaX = pontoTransfEventoAtual.x
								- desenhoSelecionado.getMaxX();
						novoDeltaY = pontoTransfEventoAtual.y
								- desenhoSelecionado.getMaxY();
						break;
					case PONTO_ESCALA_TOPO_MEIO:
						ref = (Coords) desenhoSelecionado.getMax().clone();
						antDeltaX = 1;
						antDeltaY = desenhoSelecionado.getMinY()
								- desenhoSelecionado.getMaxY();
						novoDeltaX = 1;
						novoDeltaY = pontoTransfEventoAtual.y
								- desenhoSelecionado.getMaxY();
						break;
					case PONTO_ESCALA_TOPO_DIREITA:
						ref = new Coords(desenhoSelecionado.getMinX(),
								desenhoSelecionado.getMaxY());
						antDeltaX = desenhoSelecionado.getMaxX()
								- desenhoSelecionado.getMinX();
						antDeltaY = desenhoSelecionado.getMinY()
								- desenhoSelecionado.getMaxY();
						novoDeltaX = pontoTransfEventoAtual.x
								- desenhoSelecionado.getMinX();
						novoDeltaY = pontoTransfEventoAtual.y
								- desenhoSelecionado.getMaxY();
						break;
					case PONTO_ESCALA_DIREITA_MEIO:
						ref = (Coords) desenhoSelecionado.getMin().clone();
						antDeltaX = desenhoSelecionado.getMaxX()
								- desenhoSelecionado.getMinX();
						antDeltaY = 1;
						novoDeltaX = pontoTransfEventoAtual.x
								- desenhoSelecionado.getMinX();
						novoDeltaY = 1;
						break;
					case PONTO_ESCALA_BASE_DIREITA:
						ref = (Coords) desenhoSelecionado.getMin().clone();
						antDeltaX = desenhoSelecionado.getMaxX()
								- desenhoSelecionado.getMinX();
						antDeltaY = desenhoSelecionado.getMaxY()
								- desenhoSelecionado.getMinY();
						novoDeltaX = pontoTransfEventoAtual.x
								- desenhoSelecionado.getMinX();
						novoDeltaY = pontoTransfEventoAtual.y
								- desenhoSelecionado.getMinY();
						break;
					case PONTO_ESCALA_BASE_MEIO:
						ref = (Coords) desenhoSelecionado.getMin().clone();
						antDeltaX = 1;
						antDeltaY = desenhoSelecionado.getMaxY()
								- desenhoSelecionado.getMinY();
						novoDeltaX = 1;
						novoDeltaY = pontoTransfEventoAtual.y
								- desenhoSelecionado.getMinY();
						break;
					case PONTO_ESCALA_BASE_ESQUERDA:
						ref = new Coords(desenhoSelecionado.getMaxX(),
								desenhoSelecionado.getMinY());
						antDeltaX = desenhoSelecionado.getMinX()
								- desenhoSelecionado.getMaxX();
						antDeltaY = desenhoSelecionado.getMaxY()
								- desenhoSelecionado.getMinY();
						novoDeltaX = pontoTransfEventoAtual.x
								- desenhoSelecionado.getMaxX();
						novoDeltaY = pontoTransfEventoAtual.y
								- desenhoSelecionado.getMinY();
						break;
					case PONTO_ESCALA_ESQUERDA_MEIO:
						ref = (Coords) desenhoSelecionado.getMax().clone();
						antDeltaX = desenhoSelecionado.getMinX()
								- desenhoSelecionado.getMaxX();
						antDeltaY = 1;
						novoDeltaX = pontoTransfEventoAtual.x
								- desenhoSelecionado.getMaxX();
						novoDeltaY = 1;
						break;
					}
					double variacaoEmX = (double) (novoDeltaX)
							/ (double) (antDeltaX);
					double variacaoEmY = (double) novoDeltaY
							/ (double) antDeltaY;

					Log.v(null, "variacaoEmX: " + variacaoEmX
							+ " variacaoEmY: " + variacaoEmY);
					if (variacaoEmX != 1 || variacaoEmY != 1) {
						if (variacaoEmX > 0 && variacaoEmY > 0) {
							transformou = true;
							desenhoSelecionado.escala(ref, variacaoEmX,
									variacaoEmY);

							retanguloSelecao = destacarDesenhoModoEscala(desenhoSelecionado);

							synchronized (areaDeDesenho.bitmap) {
								redesenhar();
							}
						}
					}
				} catch (CloneNotSupportedException e) {
					Log.d(null, e.getClass() + " : " + getClass()
							+ ".transformacaoInterativa()", e);
				} catch (NullPointerException e) {
					Log.d(null, e.getClass() + " : " + getClass()
							+ ".transformacaoInterativa()", e);
				}
			}
		}
		pontoTransfEventoAnt = pontoTransfEventoAtual;
	}

	private void alternaParaModoDeEscala() {
		Log.v(null, "Alternado para escala");
		retanguloSelecao = destacarDesenhoModoEscala(desenhoSelecionado);
	}

	private void alternaParaModoDeRotacao() {
		Log.v(null, "Alternado para rotacao");
		retanguloSelecao = destacarDesenhoModoRotacao(desenhoSelecionado);
	}

	private void removeSelecao() {
		if (desenhoSelecionado != null || retanguloSelecao != null) {
			desenhoSelecionado = null;
			retanguloSelecao = null;
			synchronized (areaDeDesenho.bitmap) {
				redesenhar();
			}
		}
	}

	public boolean onTouch(View v, MotionEvent event) {
		finalizaPoligonoSeNaoTiverSidoFeitoExplicitamente();
		switch (acao) {
		case MOVER:
			transformacaoInterativa(event);
			return transformando;
		case DESENHAR_RETA:
			removeSelecao();
			desenhoInterativoReta(event);
			break;
		case DESENHAR_POLIGONO:
			removeSelecao();
			desenhoInterativoPoligono(event);
			break;
		case DESENHAR_CIRCUNFERENCIA:
			removeSelecao();
			desenhoInterativoCircunferencia(event);
			break;
		case DESENHAR_RETANGULO:
			removeSelecao();
			desenhoInterativoRetangulo(event);
			break;
		case RECORTE:
			removeSelecao();
			recorteInterativo(event);
			break;
		case PREECHIMENTO:
			removeSelecao();
			preechimento(event);
			return false; // pegar apenas um ponto
		default:

			return false;
		}

		return true;
	}

	private boolean desenhandoRetanguloParaRecorte = false;

	private boolean existeRetanguloParaRecorteJahDesenhado = false;

	private void recorteInterativo(MotionEvent event) {
		desenhandoRetanguloParaRecorte = true;
		desenhoInterativoRetangulo(event);
	}

	

	public static final int COR_BORDA_RETANGULO_SELECAO = Color.LTGRAY;

	private static final int TAM_LADO_QUADRADINHO_REDIM = 10;

	private ObjetoDeDesenho criarQuadradinhoRedimensionar(Coords ponto) {
		Retangulo quadrado = null;
		try {
			Coords pontoReal = new Coords(0, 0);
			pontoReal.x = ponto.x - TAM_LADO_QUADRADINHO_REDIM / 2;
			pontoReal.y = ponto.y - TAM_LADO_QUADRADINHO_REDIM / 2;
			quadrado = fabricaDeObjetoDeDesenho.createRetangulo(pontoReal,
					TAM_LADO_QUADRADINHO_REDIM, TAM_LADO_QUADRADINHO_REDIM,
					COR_BORDA_RETANGULO_SELECAO, Color.TRANSPARENT);
		} catch (Exception e) {
			Log.d(null, "Excecao lancada em " + getClass()
					+ ".criarQuadradinhoRedimensionar()", e);
		}

		return quadrado;
	}

	private static final int DISTANCIA_QUADRADINHO_REDIM = 0;

	private DesenhoComposto quadradinhosEscala = null;

	private DesenhoComposto setinhasRotacao = null;

	private DesenhoComposto criarQuadradinhosEscala(Retangulo retangulo) {
		DesenhoComposto quadradinhosEscala = new DesenhoComposto();
		int minX = retangulo.getMinX();
		int minY = retangulo.getMinY();
		int maxX = retangulo.getMaxX();
		int maxY = retangulo.getMaxY();

		// PONTO_ESCALA_TOPO_ESQUERDA
		Coords coordsQuadradinhoRedimTopoEsq = new Coords(minX
				- DISTANCIA_QUADRADINHO_REDIM, minY
				- DISTANCIA_QUADRADINHO_REDIM);
		quadradinhosEscala.listaDeDesenhos
				.add(criarQuadradinhoRedimensionar(coordsQuadradinhoRedimTopoEsq));
		// PONTO_ESCALA_TOPO_MEIO
		Coords coordsQuadradinhoRedimMeioTopo = new Coords(((maxX - minX) / 2)
				+ minX, minY - DISTANCIA_QUADRADINHO_REDIM);
		quadradinhosEscala.listaDeDesenhos
				.add(criarQuadradinhoRedimensionar(coordsQuadradinhoRedimMeioTopo));
		// PONTO_ESCALA_TOPO_DIREITA
		Coords coordsQuadradinhoRedimTopoDir = new Coords(maxX
				+ DISTANCIA_QUADRADINHO_REDIM, minY
				- DISTANCIA_QUADRADINHO_REDIM);
		quadradinhosEscala.listaDeDesenhos
				.add(criarQuadradinhoRedimensionar(coordsQuadradinhoRedimTopoDir));
		// PONTO_ESCALA_DIREITA_MEIO
		Coords coordsQuadradinhoRedimMeioDir = new Coords(maxX
				+ DISTANCIA_QUADRADINHO_REDIM, ((maxY - minY) / 2) + minY);
		quadradinhosEscala.listaDeDesenhos
				.add(criarQuadradinhoRedimensionar(coordsQuadradinhoRedimMeioDir));
		// PONTO_ESCALA_BASE_DIREITA
		Coords coordsQuadradinhoRedimBaseDir = new Coords(maxX
				+ DISTANCIA_QUADRADINHO_REDIM, maxY
				+ DISTANCIA_QUADRADINHO_REDIM);
		quadradinhosEscala.listaDeDesenhos
				.add(criarQuadradinhoRedimensionar(coordsQuadradinhoRedimBaseDir));
		// PONTO_ESCALA_BASE_MEIO
		Coords coordsQuadradinhoRedimMeioBase = new Coords(((maxX - minX) / 2)
				+ minX, maxY + DISTANCIA_QUADRADINHO_REDIM);
		quadradinhosEscala.listaDeDesenhos
				.add(criarQuadradinhoRedimensionar(coordsQuadradinhoRedimMeioBase));
		// PONTO_ESCALA_BASE_ESQUERDA
		Coords coordsQuadradinhoRedimBaseEsq = new Coords(minX
				- DISTANCIA_QUADRADINHO_REDIM, maxY
				+ DISTANCIA_QUADRADINHO_REDIM);
		quadradinhosEscala.listaDeDesenhos
				.add(criarQuadradinhoRedimensionar(coordsQuadradinhoRedimBaseEsq));
		// PONTO_ESCALA_ESQUERDA_MEIO
		Coords coordsQuadradinhoRedimMeioEsq = new Coords(minX
				- DISTANCIA_QUADRADINHO_REDIM, ((maxY - minY) / 2) + minY);
		quadradinhosEscala.listaDeDesenhos
				.add(criarQuadradinhoRedimensionar(coordsQuadradinhoRedimMeioEsq));

		return quadradinhosEscala;
	}

	private Retangulo criarRetanguloDeDestaque(
			ObjetoDeDesenho desenhoSelecionado) {
		Retangulo retangulo = null;
		try {
			Coords pontoA = (Coords) desenhoSelecionado.getMin().clone();
			Coords pontoB = (Coords) desenhoSelecionado.getMax().clone();
			pontoA.x--;
			pontoA.y--;
			pontoB.x++;
			pontoB.y++;

			retangulo = fabricaDeObjetoDeDesenho.createRetangulo(pontoA,
					pontoB, COR_BORDA_RETANGULO_SELECAO, Color.TRANSPARENT);
			retangulo.setEspessuraBorda(1);
		} catch (Exception e) {
			Log.d(null, e.getClass() + " : " + getClass()
					+ ".criarRetanguloDeDestaque()", e);
		}
		return retangulo;
	}

	private Poligono criarSetinha() {
		Poligono seta;
		seta = fabricaDeObjetoDeDesenho.createPoligono(
				COR_BORDA_RETANGULO_SELECAO, Color.TRANSPARENT);
		seta.setEspessuraBorda(1);
		seta.listaDeVertices.add(new Coords(-3, 10));
		seta.listaDeVertices.add(new Coords(0, 0));
		seta.listaDeVertices.add(new Coords(0, 20));
		seta.listaDeVertices.add(new Coords(3, 10));
		return seta;
	}

	private static final int DESLOCAMENTO_PADRAO_SETINHA = 5;

	private DesenhoComposto criaSetinhasRotacao(Poligono retanguloDeDestaque) {
		DesenhoComposto setinhasDeRotacao = new DesenhoComposto();
		Poligono setaTmp;

		Coords centro;
		int centroX, centroY;

		// seta 0
		setaTmp = criarSetinha();
		centro = setaTmp.getCentro();
		centroX = centro.x;
		centroY = centro.y;
		setaTmp.translada(retanguloDeDestaque.getMinX() - centroX
				- DESLOCAMENTO_PADRAO_SETINHA, retanguloDeDestaque.getMinY()
				- centroY - DESLOCAMENTO_PADRAO_SETINHA);
		setaTmp.rotaciona(Math.PI / 4);
		setinhasDeRotacao.listaDeDesenhos.add(setaTmp);
		// seta 1
		setaTmp = criarSetinha();
		setaTmp.translada(retanguloDeDestaque.getMaxX() - centroX
				+ DESLOCAMENTO_PADRAO_SETINHA, retanguloDeDestaque.getMinY()
				- centroY - DESLOCAMENTO_PADRAO_SETINHA);
		setaTmp.rotaciona(Math.PI / -4);
		setinhasDeRotacao.listaDeDesenhos.add(setaTmp);

		// seta 2
		setaTmp = criarSetinha();
		setaTmp.translada(retanguloDeDestaque.getMaxX() - centroX
				+ DESLOCAMENTO_PADRAO_SETINHA, retanguloDeDestaque.getMaxY()
				- centroY + DESLOCAMENTO_PADRAO_SETINHA);
		setaTmp.rotaciona(Math.PI / 4);
		setinhasDeRotacao.listaDeDesenhos.add(setaTmp);

		// seta3
		setaTmp = criarSetinha();
		setaTmp.translada(retanguloDeDestaque.getMinX() - centroX
				- DESLOCAMENTO_PADRAO_SETINHA, retanguloDeDestaque.getMaxY()
				- centroY + DESLOCAMENTO_PADRAO_SETINHA);
		setaTmp.rotaciona(Math.PI / -4);
		setinhasDeRotacao.listaDeDesenhos.add(setaTmp);

		return setinhasDeRotacao;
	}

	private ObjetoDeDesenho destacarDesenhoModoRotacao(
			ObjetoDeDesenho desenhoSelecionado) {
		DesenhoComposto desenhoDeDestaque = new DesenhoComposto();
		Retangulo retanguloDeDestaque = criarRetanguloDeDestaque(desenhoSelecionado);
		desenhoDeDestaque.listaDeDesenhos.add(retanguloDeDestaque);
		setinhasRotacao = criaSetinhasRotacao(retanguloDeDestaque);
		desenhoDeDestaque.listaDeDesenhos.add(setinhasRotacao);
		return desenhoDeDestaque;
	}

	private ObjetoDeDesenho destacarDesenhoModoEscala(
			ObjetoDeDesenho desenhoSelecionado) {
		DesenhoComposto desenhoDeDestaque = null;
		try {
			desenhoDeDestaque = new DesenhoComposto();
			Retangulo retanguloDeDestaque = criarRetanguloDeDestaque(desenhoSelecionado);
			desenhoDeDestaque.listaDeDesenhos.add(retanguloDeDestaque);

			quadradinhosEscala = criarQuadradinhosEscala(retanguloDeDestaque);

			// para circunferencia mascara os quadradinho dos meios
			if (desenhoSelecionado instanceof Circunferencia) {
				quadradinhosEscala.listaDeDesenhos.get(1).setCorContorno(
						Color.TRANSPARENT);
				// quadradinhosEscala.listaDeDesenhos.get(3).setCorContorno(Color.TRANSPARENT);
				quadradinhosEscala.listaDeDesenhos.get(5).setCorContorno(
						Color.TRANSPARENT);
				// quadradinhosEscala.listaDeDesenhos.get(7).setCorContorno(Color.TRANSPARENT);
			}
			desenhoDeDestaque.listaDeDesenhos.add(quadradinhosEscala);

		} catch (Exception e) {
			Log.d(null, "Execao lancada em " + getClass() + ".selecionar()", e);
		}
		return desenhoDeDestaque;
	}

	private void preechimento(MotionEvent event) {
		int x = (int) Math.round(event.getX());
		int y = (int) Math.round(event.getY());
		botaoInterromperPreechimento.setVisibility(View.VISIBLE);
		if (algoritmoDePreenchimentoSelecionado == AlgoritmoDePreenchimento.FLOOD_FILL) {
			int corAntiga = 0;
			synchronized (areaDeDesenho.bitmap) {
				corAntiga = areaDeDesenho.bitmap.getPixel(x, y);
			}

			Preechimento.floodFill(areaDeDesenho.bitmap, x, y,
					corPreenchimentoSelecionada, corAntiga);
		} else if (algoritmoDePreenchimentoSelecionado == AlgoritmoDePreenchimento.BOUNDARY_FILL) {
			Preechimento.boundaryFill(areaDeDesenho.bitmap, x, y,
					corPreenchimentoSelecionada, corBordaSelecionada);
		}
	}

	private void finalizaPoligonoSeNaoTiverSidoFeitoExplicitamente() {
		if (poligonoInterativo != null && acao != Acao.DESENHAR_POLIGONO) {
			finalizaDesenhoInterativoPoligno();
		}
	}

	private Coords pontoInicialInterativo = new Coords(0, 0);
	private Coords pontoFinalInterativo = new Coords(0, 0);
	private Reta retaInterativa = null;
	private Poligono poligonoInterativo = null;
	private Circunferencia circunferenciaInterativa = null;
	private Retangulo retanguloInterativo = null;

	private int corBordaSelecionada = Color.BLACK;
	private int corPreenchimentoSelecionada = Color.CYAN;

	private FabricaDeObjetoDeDesenho fabricaDeObjetoDeDesenho = new FabricaDeObjetoDeDesenho(
			AlgoritmosReta.DDA);

	private FabricaDeRecorte fabricaDeRecorte = new FabricaDeRecorte(
			FabricaDeRecorte.AlgoritmoRecorteReta.LIANG_BARSKY);

	private void desenhoInterativoRetangulo(MotionEvent event) {
		int x = (int) Math.round(event.getX());
		int y = (int) Math.round(event.getY());
		if (retanguloInterativo == null) {
			pontoInicialInterativo.x = pontoFinalInterativo.x = x;
			pontoInicialInterativo.y = pontoFinalInterativo.y = y;
			int corBorda = corBordaSelecionada;
			int corPreenchimento = corPreenchimentoSelecionada;
			if (desenhandoRetanguloParaRecorte) {
				corBorda = COR_BORDA_RETANGULO_SELECAO;
				corPreenchimento = Color.TRANSPARENT;
			}
			try {
				retanguloInterativo = fabricaDeObjetoDeDesenho.createRetangulo(
						pontoInicialInterativo, pontoFinalInterativo, corBorda,
						corPreenchimento);
			} catch (Exception e) {
				Log.d(null,
						"Excecao lancada em desenhoInterativoRetangulo():0", e);
			}

			areaDeDesenho.bitmapDesenhoInterativo = criarBitmap();

		} else {
			if (event.getAction() == MotionEvent.ACTION_UP) {
				try {
					desenhos.listaDeDesenhos.add((Poligono) retanguloInterativo
							.clone());
				} catch (CloneNotSupportedException e) {
					Log.d(null,
							"Excecao lancada em desenhoInterativoRetangulo():1",
							e);
				}
				retanguloInterativo.desenha(areaDeDesenho.bitmap);
				retanguloInterativo = null;

				areaDeDesenho.bitmapDesenhoInterativo = null;
				if (desenhandoRetanguloParaRecorte) {
					existeRetanguloParaRecorteJahDesenhado = true;
					acao = Acao.MOVER;
					desenhoSelecionado = desenhos.listaDeDesenhos
							.get(desenhos.listaDeDesenhos.size() - 1);
					retanguloSelecao = destacarDesenhoModoEscala(desenhoSelecionado);
					transformacaoCandidata = TipoTransformacao.ESCALA;
					botaoExecutarRecorte.setVisibility(View.VISIBLE);
					synchronized (areaDeDesenho.bitmap) {
						redesenhar();
					}
				}
			} else {
				synchronized (areaDeDesenho.bitmapDesenhoInterativo) {
					retanguloInterativo
							.limpaBorda(areaDeDesenho.bitmapDesenhoInterativo);
					pontoFinalInterativo.x = x;
					pontoFinalInterativo.y = y;
					retanguloInterativo.recalcularCoordenadasGeradas();
					retanguloInterativo
							.desenha(areaDeDesenho.bitmapDesenhoInterativo);
				}
			}
		}
	}

	private void desenhoInterativoCircunferencia(MotionEvent event) {
		int x = (int) Math.round(event.getX());
		int y = (int) Math.round(event.getY());

		if (circunferenciaInterativa == null) {

			areaDeDesenho.bitmapDesenhoInterativo = criarBitmap();

			pontoInicialInterativo.x = x;
			pontoInicialInterativo.y = y;
			try {
				circunferenciaInterativa = fabricaDeObjetoDeDesenho
						.createCircunferencia(
								(Coords) pontoInicialInterativo.clone(), 0,
								corBordaSelecionada,
								corPreenchimentoSelecionada);
			} catch (CloneNotSupportedException e) {
				Log.d(null,
						"Excecao lancada em desenhoInterativoCircunferencia():0",
						e);
			}
		} else {
			if (event.getAction() == MotionEvent.ACTION_UP) {
				try {
					desenhos.listaDeDesenhos
							.add((Circunferencia) circunferenciaInterativa
									.clone());
				} catch (CloneNotSupportedException e) {
					Log.d(null,
							"Excecao lancada em desenhoInterativoCircunferencia():1",
							e);
				}
				circunferenciaInterativa.desenha(areaDeDesenho.bitmap);
				circunferenciaInterativa = null;

				areaDeDesenho.bitmapDesenhoInterativo = null;

			} else {
				int raio = (int) Math.round(Math.sqrt(Math.pow(
						pontoInicialInterativo.x - x, 2)
						+ Math.pow(pontoInicialInterativo.y - y, 2)));
				synchronized (areaDeDesenho.bitmapDesenhoInterativo) {
					circunferenciaInterativa
							.limpaBorda(areaDeDesenho.bitmapDesenhoInterativo);
					circunferenciaInterativa.setRaio(raio);
					circunferenciaInterativa
							.desenha(areaDeDesenho.bitmapDesenhoInterativo);
				}
			}
		}
	}

	private void inicializaDesenhoInterativoReta() {
		retaInterativa = fabricaDeObjetoDeDesenho.createReta(
				pontoInicialInterativo, pontoFinalInterativo,
				corBordaSelecionada);

		areaDeDesenho.bitmapDesenhoInterativo = criarBitmap();

	}

	private void finalizaDesenhoInterativoReta() {
		retaInterativa = null;

		areaDeDesenho.bitmapDesenhoInterativo = null;

	}

	private void desenhoInterativoReta(MotionEvent event) {
		int x = (int) Math.round(event.getX());
		int y = (int) Math.round(event.getY());
		if (retaInterativa == null) {
			pontoInicialInterativo.x = pontoFinalInterativo.x = x;
			pontoInicialInterativo.y = pontoFinalInterativo.y = y;
			inicializaDesenhoInterativoReta();
		} else {
			if (event.getAction() == MotionEvent.ACTION_UP) {
				try {
					desenhos.listaDeDesenhos.add((Reta) retaInterativa.clone());
				} catch (CloneNotSupportedException e) {
					Log.d(null, "Excecao lancada em desenhoInterativoReta():0",
							e);
				}
				retaInterativa.desenha(areaDeDesenho.bitmap);

				finalizaDesenhoInterativoReta();
			} else {
				synchronized (areaDeDesenho.bitmapDesenhoInterativo) {
					retaInterativa
							.limpaBorda(areaDeDesenho.bitmapDesenhoInterativo);
					pontoFinalInterativo.x = x;
					pontoFinalInterativo.y = y;
					retaInterativa
							.desenha(areaDeDesenho.bitmapDesenhoInterativo);
				}
			}
		}
	}

	// finalizacao do poligono aberto (por ter selecionado outra operacao
	// e nao ter tocado no botao fechar (o poligono fica aberto)
	private void finalizaDesenhoInterativoPoligno() {
		finalizaDesenhoInterativoPoligno(false);
	}

	private void finalizaDesenhoInterativoPoligno(boolean fechar) {
		finalizaDesenhoInterativoReta();
		if (fechar) {
			try {
				poligonoInterativo.fechar();
			} catch (Exception e) {
				Log.d(null,
						"Excecao lancada em finalizaDesenhoInterativoPoligno():0",
						e);
			}
			poligonoInterativo.desenhaUltimoSegmento(areaDeDesenho.bitmap);
		}
		try {
			desenhos.listaDeDesenhos.add((Poligono) poligonoInterativo.clone());
		} catch (CloneNotSupportedException e) {
			Log.v(null,
					"Excecao lancada em finalizaDesenhoInterativoPoligno():1",
					e);
		}
		poligonoInterativo = null;
		botaoFecharPoligono.setVisibility(View.INVISIBLE);
	}

	private void desenhoInterativoPoligono(MotionEvent event) {
		int x = (int) Math.round(event.getX());
		int y = (int) Math.round(event.getY());
		if (poligonoInterativo == null) {
			pontoInicialInterativo.x = pontoFinalInterativo.x = x;
			pontoInicialInterativo.y = pontoFinalInterativo.y = y;
			inicializaDesenhoInterativoReta();
			poligonoInterativo = fabricaDeObjetoDeDesenho.createPoligono(
					corBordaSelecionada, corPreenchimentoSelecionada);
			try {
				poligonoInterativo
						.adicionarVertice((Coords) pontoInicialInterativo
								.clone());
			} catch (Exception e) {
				Log.d(null, "Excecao lancada em desenhoInterativoPoligono():0",
						e);
			}
		} else {
			if (event.getAction() == MotionEvent.ACTION_UP) {
				try {
					poligonoInterativo
							.adicionarVertice((Coords) pontoFinalInterativo
									.clone());
				} catch (Exception e) {
					Log.d(null,
							"Excecao lancada em desenhoInterativoPoligono():1",
							e);
				}
				poligonoInterativo.desenhaUltimoSegmento(areaDeDesenho.bitmap);
				finalizaDesenhoInterativoReta();
				botaoFecharPoligono.setVisibility(View.VISIBLE);

			} else if (retaInterativa == null) {
				botaoFecharPoligono.setVisibility(View.INVISIBLE);
				try {
					pontoInicialInterativo = (Coords) pontoFinalInterativo
							.clone();
				} catch (CloneNotSupportedException e) {
					Log.d(null,
							"Excecao lancada em desenhoInterativoPoligono():2",
							e);
				}
				pontoFinalInterativo.x = x;
				pontoFinalInterativo.y = y;
				inicializaDesenhoInterativoReta();
			} else {
				synchronized (areaDeDesenho.bitmapDesenhoInterativo) {
					retaInterativa
							.limpaBorda(areaDeDesenho.bitmapDesenhoInterativo);
					pontoFinalInterativo.x = x;
					pontoFinalInterativo.y = y;
					retaInterativa
							.desenha(areaDeDesenho.bitmapDesenhoInterativo);
				}
			}
		}
	}

	private void executarRecorte() {
		int idxListaDeDesenhos = desenhos.listaDeDesenhos.size() - 1;
		Poligono retanguloDeRecorte = (Poligono) desenhos.listaDeDesenhos
				.get(idxListaDeDesenhos);
		Recorte recorte = fabricaDeRecorte.criar(retanguloDeRecorte.getMin(),
				retanguloDeRecorte.getMax());
		desenhos.listaDeDesenhos.remove(idxListaDeDesenhos);
		existeRetanguloParaRecorteJahDesenhado = false;
		desenhos = (DesenhoComposto) recorte.recorta(desenhos);
		desenhos.recicla();
		desenhoSelecionado = null;
		retanguloSelecao = null;
		desenhandoRetanguloParaRecorte = false;
		botaoExecutarRecorte.setVisibility(View.INVISIBLE);
		acao = Acao.MOVER;
		synchronized (areaDeDesenho.bitmap) {
			redesenhar();
		}
	}

	private void cancelaRecorte() {
		if (desenhandoRetanguloParaRecorte) {
			int idxListaDeDesenhos = desenhos.listaDeDesenhos.size() - 1;
			if (existeRetanguloParaRecorteJahDesenhado) {
				desenhos.listaDeDesenhos.remove(idxListaDeDesenhos);
				existeRetanguloParaRecorteJahDesenhado = false;
			}
			desenhoSelecionado = null;
			retanguloSelecao = null;
			desenhandoRetanguloParaRecorte = false;
			botaoExecutarRecorte.setVisibility(View.INVISIBLE);
			acao = Acao.MOVER;
			synchronized (areaDeDesenho.bitmap) {
				redesenhar();
			}
		}
	}

	public void onClick(View v) {
		if (v.equals(botaoFecharPoligono)) {
			finalizaDesenhoInterativoPoligno(true);
		} else if (v.equals(botaoInterromperPreechimento)) {
			Preechimento.interromper();
		} else if (v.equals(botaoExecutarRecorte)) {
			executarRecorte();
		}
	}

	@Override
	protected void onStop() {
		super.onStop();
		finish();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		finish();
	}

	public void onPronto() {
		botaoInterromperPreechimento.setVisibility(View.INVISIBLE);
	}

	public void onCancel(AmbilWarnaDialog dialog) {

	}

	public void onOk(AmbilWarnaDialog dialog, int color) {
		if (dialog == colorDialogPreechimento) {
			corPreenchimentoSelecionada = color;
		} else if (dialog == colorDialogBorda) {
			corBordaSelecionada = color;
			if (desenhoSelecionado != null) {
				desenhoSelecionado.setCorContorno(color);
				synchronized (areaDeDesenho.bitmap) {
					redesenhar();
				}
			}
		}
	}

}
